Interactive Widgets

Using interact

Source Link


In [2]:
# Start with some imports!

from __future__ import print_function
from ipywidgets import interact, interactive, fixed
import ipywidgets as widgets

In [3]:
# Very basic function
def f(x):
    return x

In [7]:
help(interact)


Help on function interact in module ipywidgets.widgets.interaction:

interact(__interact_f=None, **kwargs)
    Displays interactive widgets which are tied to a function.
    Expects the first argument to be a function. Parameters to this function are
    widget abbreviations passed in as keyword arguments (`**kwargs`). Can be used
    as a decorator (see examples).
    
    Returns
    -------
    f : __interact_f with interactive widget attached to it.
    
    Parameters
    ----------
    __interact_f : function
        The function to which the interactive widgets are tied. The `**kwargs`
        should match the function signature. Passed to :func:`interactive()`
    **kwargs : various, optional
        An interactive widget is created for each keyword argument that is a
        valid widget abbreviation. Passed to :func:`interactive()`
    
    Examples
    --------
    Render an interactive text field that shows the greeting with the passed in
    text::
    
       # 1. Using interact as a function
       def greeting(text="World"):
           print "Hello {}".format(text)
       interact(greeting, text="IPython Widgets")
    
       # 2. Using interact as a decorator
       @interact
       def greeting(text="World"):
           print "Hello {}".format(text)
    
       # 3. Using interact as a decorator with named parameters
       @interact(text="IPython Widgets")
       def greeting(text="World"):
           print "Hello {}".format(text)
    
    Render an interactive slider widget and prints square of number::
    
       # 1. Using interact as a function
       def square(num=1):
           print "{} squared is {}".format(num, num*num)
       interact(square, num=5)
    
       # 2. Using interact as a decorator
       @interact
       def square(num=2):
           print "{} squared is {}".format(num, num*num)
    
       # 3. Using interact as a decorator with named parameters
       @interact(num=5)
       def square(num=2):
           print "{} squared is {}".format(num, num*num)

Note the semicolon


In [8]:
# Generate a slider to interact with
interact(f, x=10);


10

In [9]:
interact(f, x=10,);


10

Booleans create checkbox


In [10]:
# Booleans generate check-boxes
interact(f, x=True);


True

In [11]:
# Strings generate text areas
interact(f, x='Hi there!');


u'Hi there!'

Using decorators


In [12]:
# Using a decorator!
@interact(x=True, y=1.0)
def g(x, y):
    return (x, y)


(True, 1.0)

In [13]:
# Again, a simple function
def h(p, q):
    return (p, q)

In [14]:
interact(h, p=5, q=fixed(20));


(5, 20)

In [15]:
interact(f, x=widgets.IntSlider(min=-10., max=30, value=10));


10

From Portilla's notes

This examples clarifies how interact process its keyword arguments:

  1. If the keyword argument is a Widget instance with a value attribute, that widget is used. Any widget with a value attribute can be used, even custom ones.
  2. Otherwise, the value is treated as a widget abbreviation that is converted to a widget before it is used.

The following table gives an overview of different widget abbreviations:

Keyword argumentWidget
`True` or `False`Checkbox
`'Hi there'`Text
`value` or `(min,max)` or `(min,max,step)` if integers are passedIntSlider
`value` or `(min,max)` or `(min,max,step)` if floats are passedFloatSlider
`('orange','apple')` or `{'one':1,'two':2}`Dropdown

In [16]:
# Min,Max slider with Tuples
interact(f, x=(0,4));


2

In [17]:
# (min, max, step)
interact(f, x=(0,8,2));


4

In [18]:
interact(f, x=(0.0,10.0));


5.0

In [19]:
interact(f, x=(0.0,10.0,0.01));


4.99

In [20]:
@interact(x=(0.0,20.0,0.5))
def h(x=5.5):
    return x


5.5

In [21]:
interact(f, x=('apples','oranges'));


u'apples'

In [22]:
interact(f, x={'one': 10, 'two': 20});


20

In [23]:
def f(x:True): # python 3 only
    return x


  File "<ipython-input-23-6fd10fb9d2d3>", line 1
    def f(x:True): # python 3 only
           ^
SyntaxError: invalid syntax

In [24]:
from IPython.utils.py3compat import annotate

In [25]:
@annotate(x=True)
def f(x):
    return x

In [26]:
interact(f);


True

In [27]:
def f(a, b):
    return a+b

In [28]:
w = interactive(f, a=10, b=20)

In [29]:
type(w)


Out[29]:
ipywidgets.widgets.widget_box.Box

In [30]:
w.children


Out[30]:
(<ipywidgets.widgets.widget_int.IntSlider at 0x10a7493d0>,
 <ipywidgets.widgets.widget_int.IntSlider at 0x10a720b50>)

In [31]:
from IPython.display import display
display(w)


30

In [32]:
w.kwargs


Out[32]:
{'a': 10, 'b': 20}

In [33]:
w.result


Out[33]:
30

In [34]:
from ipywidgets import *

In [41]:
IntSlider()

In [40]:
from IPython.display import display
w = IntSlider()
display(w)

In [42]:
display(w)

multiple instances remain in sync!


In [43]:
w.close()

In [44]:
w = IntSlider()
display(w)

In [45]:
w.value


Out[45]:
0

In [46]:
w.value = 100

In [47]:
w.keys


Out[47]:
['_view_name',
 'orientation',
 'color',
 '_view_module',
 'disabled',
 'visible',
 'readout_format',
 '_model_module',
 'font_style',
 'layout',
 'min',
 '_range',
 'background_color',
 'slider_color',
 'continuous_update',
 'font_family',
 '_dom_classes',
 'description',
 '_model_name',
 'max',
 'readout',
 'font_weight',
 'step',
 'font_size',
 'msg_throttle',
 'value']

In [49]:
Text(value='Hello World!')

In [50]:
Text(value='Hello World!', disabled=True)

In [51]:
from traitlets import link
a = FloatText()
b = FloatSlider()
display(a,b)

mylink = link((a, 'value'), (b, 'value'))

In [52]:
mylink.unlink()

In [53]:
print(widgets.Button.on_click.__doc__)


Register a callback to execute when the button is clicked.

        The callback will be called with one argument, the clicked button
        widget instance.

        Parameters
        ----------
        remove: bool (optional)
            Set to true to remove the callback from the list of callbacks.
        

In [54]:
from IPython.display import display
button = widgets.Button(description="Click Me!")
display(button)

def on_button_clicked(b):
    print("Button clicked.")

button.on_click(on_button_clicked)


Button clicked.
Button clicked.
Button clicked.

In [55]:
text = widgets.Text()
display(text)

def handle_submit(sender):
    print(text.value)

text.on_submit(handle_submit)


hello!
hello hello!


olleh!

In [56]:
print(widgets.Widget.on_trait_change.__doc__)


DEPRECATED: Setup a handler to be called when a trait changes.

        This is used to setup dynamic notifications of trait changes.

        Static handlers can be created by creating methods on a HasTraits
        subclass with the naming convention '_[traitname]_changed'.  Thus,
        to create static handler for the trait 'a', create the method
        _a_changed(self, name, old, new) (fewer arguments can be used, see
        below).

        If `remove` is True and `handler` is not specified, all change
        handlers for the specified name are uninstalled.

        Parameters
        ----------
        handler : callable, None
            A callable that is called when a trait changes.  Its
            signature can be handler(), handler(name), handler(name, new),
            handler(name, old, new), or handler(name, old, new, self).
        name : list, str, None
            If None, the handler will apply to all traits.  If a list
            of str, handler will apply to all names in the list.  If a
            str, the handler will apply just to that name.
        remove : bool
            If False (the default), then install the handler.  If True
            then unintall it.
        

In [ ]:
print(widgets.obse)

In [59]:
int_range = widgets.IntSlider()
display(int_range)

def on_value_change(name, value):
    print(value)

int_range.on_trait_change(on_value_change, 'value')


/usr/local/lib/python2.7/site-packages/ipykernel/__main__.py:7: DeprecationWarning:

on_trait_change is deprecated in traitlets 4.1: use observe instead

1
5
7
11
18
19
20
21
23
29
30
31
32
34
35
38
39
37
36
35
34
32
31
30

In [60]:
import traitlets

In [62]:
# Create Caption
caption = widgets.Label(value = 'The values of slider1 and slider2 are synchronized')

# Create IntSlider
slider1 = widgets.IntSlider(description='Slider 1')
slider2 =  widgets.IntSlider(description='Slider 2')

# Use trailets to link
l = traitlets.link((slider1, 'value'), (slider2, 'value'))

# Display!
display(caption, slider1, slider2)

In [63]:
# Create Caption
caption = widgets.Latex(value = 'Changes in source values are reflected in target1')

# Create Sliders
source = widgets.IntSlider(description='Source')
target1 = widgets.IntSlider(description='Target 1')

# Use dlink
dl = traitlets.dlink((source, 'value'), (target1, 'value'))
display(caption, source, target1)

In [64]:
# May get an error depending on order of cells being run!
l.unlink()
dl.unlink()

There are client-server nuances!


In [65]:
# NO LAG VERSION
caption = widgets.Latex(value = 'The values of range1 and range2 are synchronized')

range1 = widgets.IntSlider(description='Range 1')
range2 =  widgets.IntSlider(description='Range 2')

l = widgets.jslink((range1, 'value'), (range2, 'value'))
display(caption, range1, range2)

In [66]:
# NO LAG VERSION
caption = widgets.Latex(value = 'Changes in source_range values are reflected in target_range1')

source_range = widgets.IntSlider(description='Source range')
target_range1 = widgets.IntSlider(description='Target range ')

dl = widgets.jsdlink((source_range, 'value'), (target_range1, 'value'))
display(caption, source_range, target_range1)

In [67]:
l.unlink()
dl.unlink()

In [68]:
import ipywidgets as widgets

# Show all available widgets!
widgets.Widget.widget_types.values()


Out[68]:
[ipywidgets.widgets.widget_int.IntRangeSlider,
 ipywidgets.widgets.widget_selection.RadioButtons,
 ipywidgets.widgets.widget_int.Play,
 ipywidgets.widgets.widget_controller.Axis,
 ipywidgets.widgets.widget_float.FloatSlider,
 ipywidgets.widgets.widget_int.IntSlider,
 ipywidgets.widgets.widget_image.Image,
 ipywidgets.widgets.widget_selection.SelectMultiple,
 ipywidgets.widgets.widget_string.HTML,
 ipywidgets.widgets.widget_box.Box,
 ipywidgets.widgets.widget_float.BoundedFloatText,
 ipywidgets.widgets.widget_selectioncontainer.Accordion,
 ipywidgets.widgets.widget_button.Button,
 ipywidgets.widgets.widget_bool.Valid,
 ipywidgets.widgets.widget_bool.Checkbox,
 ipywidgets.widgets.widget_selection.SelectionSlider,
 ipywidgets.widgets.widget_box.Proxy,
 ipywidgets.widgets.widget_string.Text,
 ipywidgets.widgets.widget_selection.ToggleButtons,
 ipywidgets.widgets.widget_float.FloatRangeSlider,
 ipywidgets.widgets.widget_color.ColorPicker,
 ipywidgets.widgets.widget_selection.Dropdown,
 ipywidgets.widgets.widget_string.Label,
 ipywidgets.widgets.widget_controller.Controller,
 ipywidgets.widgets.widget_box.PlaceProxy,
 ipywidgets.widgets.widget_float.FloatText,
 ipywidgets.widgets.widget_box.FlexBox,
 ipywidgets.widgets.widget_link.DirectionalLink,
 ipywidgets.widgets.widget_bool.ToggleButton,
 ipywidgets.widgets.widget_selection.Select,
 ipywidgets.widgets.widget_int.IntProgress,
 ipywidgets.widgets.widget_string.Textarea,
 ipywidgets.widgets.widget_selectioncontainer.Tab,
 ipywidgets.widgets.widget_int.IntText,
 ipywidgets.widgets.widget_float.FloatProgress,
 ipywidgets.widgets.widget_int.BoundedIntText,
 ipywidgets.widgets.widget_link.Link,
 ipywidgets.widgets.widget_controller.Button]

In [69]:
widgets.FloatSlider(
    value=7.5,
    min=5.0,
    max=10.0,
    step=0.1,
    description='Test:',
)

In [70]:
widgets.FloatSlider(
    value=7.5,
    min=5.0,
    max=10.0,
    step=0.1,
    description='Test',
    orientation='vertical',
)

In [71]:
widgets.FloatProgress(
    value=7.5,
    min=5.0,
    max=10.0,
    step=0.1,
    description='Loading:',
)

In [72]:
widgets.BoundedFloatText(
    value=7.5,
    min=5.0,
    max=10.0,
    description='Text:',
)

In [73]:
widgets.FloatText(
    value=7.5,
    description='Any:',
)

In [74]:
widgets.ToggleButton(
    description='Click me',
    value=False,
)

In [75]:
widgets.Checkbox(
    description='Check me',
    value=True,
)

In [76]:
widgets.Valid(
    value=True,
)

In [77]:
from IPython.display import display

w = widgets.Dropdown(
    options=['1', '2', '3'],
    value='2',
    description='Number:',
)
display(w)

In [78]:
# Show value
w.value


Out[78]:
'2'

In [79]:
w = widgets.Dropdown(
    options={'One': 1, 'Two': 2, 'Three': 3},
    value=2,
    description='Number:')

display(w)

In [80]:
w.value


Out[80]:
1

In [81]:
widgets.RadioButtons(
    description='Pizza topping:',
    options=['pepperoni', 'pineapple', 'anchovies'],
)

In [82]:
widgets.Select(
    description='OS:',
    options=['Linux', 'Windows', 'OSX'],
)

In [83]:
widgets.ToggleButtons(
    description='Speed:',
    options=['Slow', 'Regular', 'Fast'],
)

In [84]:
w = widgets.SelectMultiple(
    description="Fruits",
    options=['Apples', 'Oranges', 'Pears'])

display(w)

In [85]:
w.value


Out[85]:
('Oranges', 'Pears')

In [86]:
widgets.Text(
    description='String:',
    value='Hello World',
)

In [87]:
widgets.Textarea(
    description='String:',
    value='Hello World',
)

In [88]:
widgets.Latex(
    value="$$\\frac{n!}{k!(n-k)!}$$",
)

In [89]:
widgets.HTML(
    value="Hello <b>World</b>"
)

In [90]:
widgets.Button(description='Click me')

Source

With mroe text descriptions


In [97]:
%%html
<style>
.example-container { background: #999999; padding: 2px; min-height: 100px; }
.example-container.sm { min-height: 50px; }
.example-box { background: #9999FF; width: 50px; height: 50px; text-align: center; vertical-align: middle; color: white; font-weight: bold; margin: 2px;}
.example-box.med { width: 65px; height: 65px; }   
.example-box.lrg { width: 80px; height: 80px; }   
</style>



In [92]:
import ipywidgets as widgets
from IPython.display import display

In [98]:
button = widgets.Button(
    description='Hello World!',
    width=100, # Integers are interpreted as pixel measurements.
    height='2em', # em is valid HTML unit of measurement.
    color='lime', # Colors can be set by name,
    background_color='#0022FF', # and also by color code.
    border_color='cyan')
display(button)

This is not working!


In [96]:
from IPython.display import display

float_range = widgets.FloatSlider()
string = widgets.Text(value='hi')
container = widgets.Box(children=[float_range, string])

container.border_color = 'red'
container.border_style = 'dotted'
container.border_width = 3
display(container) # Displays the `container` and all of it's children.

In [99]:
container = widgets.Box()
container.border_color = 'red'
container.border_style = 'dotted'
container.border_width = 3
display(container)

int_range = widgets.IntSlider()
container.children=[int_range]

In [100]:
name1 = widgets.Text(description='Location:')
zip1 = widgets.BoundedIntText(description='Zip:', min=0, max=99999)
page1 = widgets.Box(children=[name1, zip1])

name2 = widgets.Text(description='Location:')
zip2 = widgets.BoundedIntText(description='Zip:', min=0, max=99999)
page2 = widgets.Box(children=[name2, zip2])

accord = widgets.Accordion(children=[page1, page2], width=400)
display(accord)

accord.set_title(0, 'From')
accord.set_title(1, 'To')

In [101]:
name = widgets.Text(description='Name:', padding=4)
color = widgets.Dropdown(description='Color:', padding=4, options=['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'])
page1 = widgets.Box(children=[name, color], padding=4)

age = widgets.IntSlider(description='Age:', padding=4, min=0, max=120, value=50)
gender = widgets.RadioButtons(description='Gender:', padding=4, options=['male', 'female'])
page2 = widgets.Box(children=[age, gender], padding=4)

tabs = widgets.Tab(children=[page1, page2])
display(tabs)

tabs.set_title(0, 'Name')
tabs.set_title(1, 'Details')

In [102]:
display(widgets.Text(description="a:"))
display(widgets.Text(description="aa:"))
display(widgets.Text(description="aaa:"))

In [103]:
display(widgets.Text(description="a:"))
display(widgets.Text(description="aa:"))
display(widgets.Text(description="aaa:"))
display(widgets.Text(description="aaaaaaaaaaaaaaaaaa:"))

In [104]:
display(widgets.Text(description="a:"))
display(widgets.Text(description="aa:"))
display(widgets.Text(description="aaa:"))
display(widgets.Text())

In [105]:
buttons = [widgets.Button(description=str(i)) for i in range(3)]
display(*buttons)

In [106]:
container = widgets.HBox(children=buttons)
display(container)

In [107]:
container = widgets.VBox(children=buttons)
display(container)

In [108]:
container = widgets.FlexBox(children=buttons)
display(container)

In [109]:
w1 = widgets.Latex(value="First line")
w2 = widgets.Latex(value="Second line")
w3 = widgets.Latex(value="Third line")
display(w1, w2, w3)

In [110]:
w2.visible=None

In [111]:
w2.visible=False

In [112]:
w2.visible=True

In [114]:
form = widgets.VBox()
first = widgets.Text(description="First:")
last = widgets.Text(description="Last:")

student = widgets.Checkbox(description="Student:", value=False)
school_info = widgets.VBox(visible=False, children=[
    widgets.Text(description="School:"),
    widgets.IntText(description="Grade:", min=0, max=12)
    ])

pet = widgets.Text(description="Pet:")
form.children = [first, last, student, school_info, pet]
display(form)

def on_student_toggle(name, value):
    if value:
        school_info.visible = True
    else:
        school_info.visible = False
        
student.on_trait_change(on_student_toggle, 'value')


/usr/local/lib/python2.7/site-packages/ipykernel/__main__.py:21: DeprecationWarning:

on_trait_change is deprecated in traitlets 4.1: use observe instead


In [ ]: